package cn.aitrox.ry.service.config.service.impl;

import cn.aitrox.ry.bean.RespResult;
import cn.aitrox.ry.common.bean.Order;
import cn.aitrox.ry.common.service.BaseService;
import cn.aitrox.ry.common.service.api.dto.KV;
import cn.aitrox.ry.enumtype.RespCodeEnum;
import cn.aitrox.ry.service.config.dao.DictDao;
import cn.aitrox.ry.service.config.dto.CommonConfigDto;
import cn.aitrox.ry.service.config.entity.DictEntity;
import cn.aitrox.ry.service.config.enumtype.DictRootCodeEnum;
import cn.aitrox.ry.service.config.enumtype.ImageLayoutEnum;
import cn.aitrox.ry.service.config.enumtype.ImageTransferModeEnum;
import cn.aitrox.ry.service.config.enumtype.LesionToolBizTypeEnum;
import cn.aitrox.ry.service.config.po.dict.DictFindInPo;
import cn.aitrox.ry.service.config.service.DictService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DictServiceImpl extends BaseService implements DictService {

    @Autowired
    private DictDao dictDao;

    @Override
    public CommonConfigDto commonList(List<String> configList) {
        DictEntity cond = new DictEntity();
        cond.setParentId(0);
        List<DictEntity> list = dictDao.findAll();
        List<DictEntity> rootDictList = list.stream().filter(x -> x.getParentId() == 0).collect(Collectors.toList());

        Map<Integer, DictRootCodeEnum> rootDictEnumMap = new HashMap<>();

        for (DictEntity dict : rootDictList) {
            DictRootCodeEnum codeEnum = DictRootCodeEnum.getEnumByCode(dict.getCode());
            if (null == codeEnum) {
                continue;
            }
            rootDictEnumMap.put(dict.getId(), codeEnum);
        }

        CommonConfigDto commonConfig = new CommonConfigDto();

        for (DictEntity dict : list) {
            if (dict.getParentId() == 0) {
                continue;
            }
            DictRootCodeEnum codeEnum = rootDictEnumMap.get(dict.getParentId());
            if (null == codeEnum) {
                continue;
            }
            KV kv = new KV(dict.getName(), dict.getValue());
            switch (codeEnum) {
                case DEPARTMENT:
                    commonConfig.getDepartments().add(kv);
                    break;
                case TASK_LABEL:
                    commonConfig.getTaskLabels().add(kv);
                    break;
                case TASK_TARGET:
                    commonConfig.getTaskTargets().add(kv);
                    break;
                case TASK_USES:
                    commonConfig.getTaskUses().add(kv);
                    break;
                case DISCARD_REASON:
                    commonConfig.getDiscardReasons().add(kv);
                    break;
                case WINDOWS:
                    commonConfig.getWindows().add(kv);
                    break;
                case ALG_MODE_VERSION:
                    break;
                default:
                    break;
            }
        }

        for (ImageLayoutEnum imageLayoutEnum : ImageLayoutEnum.values()) {
            commonConfig.getImageLayouts().add(new KV(imageLayoutEnum.getDesc(), imageLayoutEnum.getValue()));
        }
        for (LesionToolBizTypeEnum bizTypeEnum : LesionToolBizTypeEnum.values()) {
            commonConfig.getLesionBizTypes().add(new KV(bizTypeEnum.getDesc(), bizTypeEnum.getBizType().toString()));
        }
        for (ImageTransferModeEnum modeEnum : ImageTransferModeEnum.values()) {
            commonConfig.getImageTransferModes().add(new KV(modeEnum.getDesc(), modeEnum.getMode()));
        }

        return commonConfig;
    }

    @Override
    public String maxCode(String codePrefix) {
        DictEntity cond = new DictEntity();
        cond.setParentId(0);
        cond.setCode(codePrefix);
        DictEntity dictEntity = dictDao.findOne(cond);
        if (null == dictEntity) {
            return null;
        }
        String maxCode = dictDao.findMaxCodeByParentId(dictEntity.getId());

        return maxCode;
    }

    @Transactional
    @Override
    public RespResult save(Integer parentId, String code, String name, String value, String remark) {
        // 校验名称是否重复
        Boolean nameExisted = this.nameExisted(null, parentId, name);
        if (nameExisted) {
            return RespResult.secByError(RespCodeEnum.EXISTED.getCode(), "名称已存在");
        }

        DictEntity cond = new DictEntity();
        cond.setCode(code);
        DictEntity dictInDb = dictDao.findOne(cond);
        if (null != dictInDb) {
            return RespResult.error(RespCodeEnum.EXISTED);
        }
        DictEntity dictEntity = new DictEntity(null, parentId, code, name, value, remark, 0);
        dictDao.insertSelective(dictEntity);

        return RespResult.ok();
    }

    @Transactional
    @Override
    public RespResult edit(Integer id, String name, String value, String remark) {
        DictEntity dictInDB = dictDao.findById(id);
        if (null == dictInDB) {
            return RespResult.error(RespCodeEnum.NOT_EXIST);
        }
        Boolean nameExisted = this.nameExisted(id, dictInDB.getParentId(), name);
        if (nameExisted) {
            return RespResult.secByError(RespCodeEnum.EXISTED.getCode(), "名称已存在");
        }
        DictEntity dictEntity = new DictEntity(id, null, null, name, value, remark, 0);
        dictDao.updateByIdSelective(dictEntity);
        return RespResult.ok();
    }

    @Override
    public PageInfo<DictEntity> search(Integer page, Integer pageSize, Integer parentId, String name) {
        return dictDao.search(page, pageSize, Order.asc("id"), new DictFindInPo(parentId, getLikeSqlParam(name)));
    }

    @Override
    public Boolean nameExisted(Integer id, Integer parentId, String name) {
        DictEntity cond = new DictEntity();
        cond.setName(name);
        cond.setParentId(parentId);
        List<DictEntity> dictListByName = dictDao.findByCondition(cond, null);
        return dictListByName.stream().filter(x -> !x.getId().equals(id) && x.getName().equals(name)).count() > 0;
    }
}
